package common.model.request.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.*;

import javax.validation.Valid;
import java.util.Collection;
import java.util.Map;

/**
 * 分页插件查询请求
 *
 * @author 米泽鹏
 * @since 2021-9-4 下午 12:22
 */
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PaginationRequest<Request, PO> extends PageRequest<PO> {

	/**
	 * 泛型参数Request中的排序字段名
	 */
	private static final String ORDER_BY = "orderby";
	@Valid
	private Request params;

	public QueryWrapper<PO> buildQueryWrapper() {
		QueryWrapper<PO> wrapper = new QueryWrapper<>();
		if (params != null) {
			Map<String, Object> paramsMap = BeanUtil.beanToMap(params);
			for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
				Object value = entry.getValue();
				if (value == null || value instanceof CharSequence && StrUtil.isBlank((CharSequence) value) || value instanceof Collection && CollUtil.isEmpty((Collection<?>) value)) {
					continue;
				}
				String keyType = entry.getKey();
				String fieldName, queryType;
				String[] split = keyType.split("_");
				if (!(split.length == 1 && ORDER_BY.equals(split[0])) && split.length < 2) {
					continue;
				}
				fieldName = StrUtil.toUnderlineCase(StrUtil.removeSuffix(keyType, "_" + split[split.length - 1]));
				queryType = split[split.length - 1];
				switch (queryType) {
					case "eq":
						wrapper.eq(fieldName, value);
						break;
					case "ne":
						wrapper.ne(fieldName, value);
						break;
					case "like":
						wrapper.like(fieldName, value);
						break;
					case "leftlike":
						wrapper.likeLeft(fieldName, value);
						break;
					case "rightlike":
						wrapper.likeRight(fieldName, value);
						break;
					case "notlike":
						wrapper.notLike(fieldName, value);
						break;
					case "gt":
						wrapper.gt(fieldName, value);
						break;
					case "lt":
						wrapper.lt(fieldName, value);
						break;
					case "ge":
						wrapper.ge(fieldName, value);
						break;
					case "le":
						wrapper.le(fieldName, value);
						break;
					case "in": {
						JSONArray valueArray = JSONUtil.parseArray(value);
						wrapper.in(fieldName, valueArray);
						break;
					}
					case ORDER_BY: {
						JSONArray orderArray = JSONUtil.parseArray(value);
						for (Object o : orderArray) {
							OrderBy orderBy = BeanUtil.toBean(o, OrderBy.class);
							String orderFieldName = StrUtil.toUnderlineCase(orderBy.getField());
							String orderType = orderBy.getOrder();
							switch (orderType) {
								case "ascending":
									wrapper.orderByAsc(orderFieldName);
									break;
								case "descending":
									wrapper.orderByDesc(orderFieldName);
									break;
								default:
									break;
							}
						}
						break;
					}
					default:
						break;
				}
			}
		}
		return wrapper;
	}

	@Data
	public static class OrderBy {
		/**
		 * 排序的字段名，驼峰命名法
		 */
		private String field;

		/**
		 * 排序类型，ascending或descending
		 */
		private String order;
	}

}
